import backtrader as bt
import logging
from datetime import datetime
from .DbOprate import DbOprate
from .TDXFunctions import TDXFunctions
from .FactorDataManager import FactorDataManager

class TDXRunDataStrategy(bt.Strategy):
    """
    通达信GPJY策略（精简版 - 只计算X_13, X_14, DDD1三个参数）
    """
    params = (
        ('d1', 20),      # 20日周期
        ('d2', 10),      # 10日周期 - 过滤周期
    )
    
    def __init__(self):
        self.data_close = self.datas[0].close
        self.data_low = self.datas[0].low
        self.tdx = TDXFunctions()
        
        # 初始化因子数据管理器
        self.stock_code = self.datas[0]._name
        self.factor_manager = FactorDataManager(self.stock_code)
        
        # 确保Redis连接正常
        try:
            self.factor_manager.redis_client.ping()
            print("Redis连接成功")
        except:
            print("Redis连接失败，将只使用数据库存储")
        
        # 在初始化时加载因子数据到Redis
        loaded_count = self.factor_manager.load_factors_to_redis()
        print(f"初始化完成，加载了 {loaded_count} 条因子数据")

        # 存储历史数据（用于计算需要历史数据的因子）
        self.history_data = {
            'close': [],
            'low': [],
            'x_13': [],
            'x_13_1': [],
            'x_13_2': [],
            'x_14': [],
            'ddd1': []
        }

    def save_factor_data(self, trade_date, factor_key, factor_val):
        """保存因子数据到数据库和Redis"""
        try:
            # 保存到数据库
            self.factor_manager.save_factor_to_db(trade_date, factor_key, factor_val)
            # 保存到Redis
            self.factor_manager.save_factor_to_redis(trade_date, factor_key, factor_val)
        except Exception as e:
            print(f"保存因子数据失败: {e}")

    def get_factor_data(self, trade_date, factor_key):
        """获取因子数据（优先从Redis获取，没有则返回None）"""
        return self.factor_manager.get_factor_from_redis(trade_date, factor_key)

    def next(self):
        current_date = self.datas[0].datetime.date(0)
        current_price = float(self.data_close[0])
        current_low = float(self.data_low[0])
        trade_date_int = int(current_date.strftime('%Y%m%d'))

        # 先尝试从Redis获取已计算的因子值
        cached_x_13 = self.get_factor_data(trade_date_int, 'X_13')
        cached_x_14 = self.get_factor_data(trade_date_int, 'X_14')
        cached_ddd1 = self.get_factor_data(trade_date_int, 'DDD1')

        # 如果有缓存数据，使用缓存
        if (cached_x_13 is not None and cached_x_13 != '' and 
            cached_x_14 is not None and cached_x_14 != '' and
            cached_ddd1 is not None and cached_ddd1 != ''):
            
            x_13_numeric = int(cached_x_13)
            x_14_value = int(cached_x_14)
            ddd1_value = float(cached_ddd1)
            
            print(f"{current_date} - 使用缓存因子数据")
        else:
            # 没有缓存，需要重新计算
            print(f"{current_date} - 计算因子数据...")
            
            # 更新历史数据
            self.history_data['close'].append(current_price)
            self.history_data['low'].append(current_low)
            
            # X_13:=CLOSE=LLV(CLOSE,D1);{是否20日最低收盘价}
            llv_value = self.tdx.LLV(self.data_close, self.p.d1)
            x_13_value = abs(current_price - llv_value) < 0.0001
            x_13_numeric = int(x_13_value)
            self.history_data['x_13'].append(x_13_numeric)
            
            # X_14:=BARSLAST(FILTER(CROSS(0.8,X_13),D2))+1;
            x_13_1_value = False
            if len(self.history_data['x_13']) >= 2:
                x_13_prev = self.history_data['x_13'][-2]
                x_13_curr = self.history_data['x_13'][-1]
                x_13_1_value = self.tdx.CROSS_simple(0.8, 0.8, x_13_prev, x_13_curr)
            self.history_data['x_13_1'].append(x_13_1_value)
            
            x_13_2_value = False
            if len(self.history_data['x_13_1']) > 0:
                all_filtered = self.tdx.FILTER(self.history_data['x_13_1'], self.p.d2)
                x_13_2_value = all_filtered[-1] if len(all_filtered) > 0 else False
            self.history_data['x_13_2'].append(x_13_2_value)
            
            barslast_value = self.tdx.BARSLAST(self.history_data['x_13_2'])
            x_14_value = barslast_value + 1
            self.history_data['x_14'].append(x_14_value)
            
            # DDD1:=REF(LOW,X_14);
            ddd1_value = self.tdx.REF(self.data_low, x_14_value)
            self.history_data['ddd1'].append(ddd1_value)
            
            # 保存计算结果到数据库和Redis
            self.save_factor_data(trade_date_int, 'X_13', x_13_numeric)
            self.save_factor_data(trade_date_int, 'X_14', x_14_value)
            self.save_factor_data(trade_date_int, 'DDD1', ddd1_value)
            
            print(f"{current_date} - 计算完成并保存因子数据")

    def stop(self):
        """策略结束时调用"""
        print(f'=== TDXGPJY策略(精简版)执行完成 ===')
